package com.bestcem.xm.member.retry;

import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.member.grpc.client.UserClient;
import com.bestcem.xm.member.grpc.client.XmMemberClient;
import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.backoff.FixedBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ming.xue <ming.xue@idiaoyan.com>
 * @desc 获取企业标识列表
 * @date 2021-08-30
 */
@Slf4j
@Component
public class ListOrgIdsRetry {
    private static final Logger EMAIL_LOG = LoggerFactory.getLogger("EmailErrorLog");

    /**
     * 用户客户端
     */
    @Autowired
    private UserClient userClient;

    @Resource
    private XmMemberClient xmMemberClient;

    public ServiceResult<List<String> > callApi(List<String> packageIds) {
        // 表示哪些异常需要重试,key表示异常的字节码,value为true表示需要重试
        Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<>();
        exceptionMap.put(StatusRuntimeException.class, true);
        // 构建重试模板实例
        RetryTemplate retryTemplate = new RetryTemplate();

        // 设置重试回退操作策略，主要设置重试间隔时间
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(5000L);

        //设置重试次数和异常类型
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3, exceptionMap);

        retryTemplate.setRetryPolicy(retryPolicy);
        retryTemplate.setBackOffPolicy(backOffPolicy);

        return retryTemplate.execute(
                retryContext -> userClient.listOrgIds(packageIds),
                recoveryContext -> {
                    Throwable throwable = recoveryContext.getLastThrowable();
                    EMAIL_LOG.error("【联系人】推送联系人打标签失败，获取企业标识列表重试失败, retryCount: {}",
                            recoveryContext.getRetryCount(), throwable);
                    return ServiceResult.fail("获取企业标识列表重试失败");
                });
    }

    public ServiceResult<List<String> > callListPackageIdsByCodeApi(String code, Integer category) {
        // 表示哪些异常需要重试,key表示异常的字节码,value为true表示需要重试
        Map<Class<? extends Throwable>, Boolean> exceptionMap = new HashMap<>();
        exceptionMap.put(StatusRuntimeException.class, true);
        // 构建重试模板实例
        RetryTemplate retryTemplate = new RetryTemplate();

        // 设置重试回退操作策略，主要设置重试间隔时间
        FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
        backOffPolicy.setBackOffPeriod(180000L);

        //设置重试次数和异常类型
        SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3, exceptionMap);

        retryTemplate.setRetryPolicy(retryPolicy);
        retryTemplate.setBackOffPolicy(backOffPolicy);

        return retryTemplate.execute(
                retryContext -> xmMemberClient.listPackageIdsByCode(code, category),
                recoveryContext -> {
                    Throwable throwable = recoveryContext.getLastThrowable();
                    EMAIL_LOG.error("【联系人】推送联系人打标签失败，获取套餐id列表失败, retryCount: {}",
                            recoveryContext.getRetryCount(), throwable);
                    return ServiceResult.fail("获取套餐id列表重试失败");
                });
    }
}
